{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'Const:0' shape=(2,) dtype=int32>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "import csv\n",
    "import random\n",
    "import numpy as np\n",
    "import random\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "batch_size = 50\n",
    "symmetry = ['rotate180', 'rotate90', 'rotate270', 'flip_v', 'flip_h']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def print_board(board):\n",
    "    symbols = ['O',' ','X']\n",
    "    board_plus1 = [int(x) + 1 for x in board]\n",
    "    print(' ' + symbols[board_plus1[0]] + ' | ' + symbols[board_plus1[1]] + ' | ' + symbols[board_plus1[2]])\n",
    "    print('___________')\n",
    "    print(' ' + symbols[board_plus1[3]] + ' | ' + symbols[board_plus1[4]] + ' | ' + symbols[board_plus1[5]])\n",
    "    print('___________')\n",
    "    print(' ' + symbols[board_plus1[6]] + ' | ' + symbols[board_plus1[7]] + ' | ' + symbols[board_plus1[8]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_symmetry(board, response, transformation):\n",
    "    '''\n",
    "    :param board: list of integers 9 long:\n",
    "     opposing mark = -1\n",
    "     friendly mark = 1\n",
    "     empty space = 0\n",
    "    :param transformation: one of five transformations on a board:\n",
    "     'rotate180', 'rotate90', 'rotate270', 'flip_v', 'flip_h'\n",
    "    :return: tuple: (new_board, new_response)\n",
    "    '''\n",
    "    if transformation == 'rotate180':\n",
    "        new_response = 8 - response\n",
    "        return(board[::-1], new_response)\n",
    "    elif transformation == 'rotate90':\n",
    "        new_response = [6, 3, 0, 7, 4, 1, 8, 5, 2].index(response)\n",
    "        tuple_board = list(zip(*[board[6:9], board[3:6], board[0:3]]))\n",
    "        return([value for item in tuple_board for value in item], new_response)\n",
    "    elif transformation == 'rotate270':\n",
    "        new_response = [2, 5, 8, 1, 4, 7, 0, 3, 6].index(response)\n",
    "        tuple_board = list(zip(*[board[0:3], board[3:6], board[6:9]]))[::-1]\n",
    "        return([value for item in tuple_board for value in item], new_response)\n",
    "    elif transformation == 'flip_v':\n",
    "        new_response = [6, 7, 8, 3, 4, 5, 0, 1, 2].index(response)\n",
    "        return(board[6:9] +  board[3:6] + board[0:3], new_response)\n",
    "    elif transformation == 'flip_h':  # flip_h = rotate180, then flip_v\n",
    "        new_response = [2, 1, 0, 5, 4, 3, 8, 7, 6].index(response)\n",
    "        new_board = board[::-1]\n",
    "        return(new_board[6:9] +  new_board[3:6] + new_board[0:3], new_response)\n",
    "    else:\n",
    "        raise ValueError('Method not implmented.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_moves_from_csv(csv_file):\n",
    "    '''\n",
    "    :param csv_file: csv file location containing the boards w/ responses\n",
    "    :return: moves: list of moves with index of best response\n",
    "    '''\n",
    "    moves = []\n",
    "    with open(csv_file, 'rt') as csvfile:\n",
    "        reader = csv.reader(csvfile, delimiter=',')\n",
    "        for row in reader:\n",
    "            moves.append(([int(x) for x in row[0:9]],int(row[9])))\n",
    "    return(moves)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_rand_move(moves, rand_transforms=2):\n",
    "    '''\n",
    "    :param moves: list of the boards w/responses\n",
    "    :param rand_transforms: how many random transforms performed on each\n",
    "    :return: (board, response), board is a list of 9 integers, response is 1 int\n",
    "    '''\n",
    "    (board, response) = random.choice(moves)\n",
    "    possible_transforms = ['rotate90', 'rotate180', 'rotate270', 'flip_v', 'flip_h']\n",
    "    for i in range(rand_transforms):\n",
    "        random_transform = random.choice(possible_transforms)\n",
    "        (board, response) = get_symmetry(board, response, random_transform)\n",
    "    return(board, response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[([1, -1, 0, -1, 0, 0, 0, 1, -1], 5), ([-1, -1, 1, 0, -1, 0, 0, 1, 0], 8), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([-1, 0, 0, 0, -1, 0, 1, 0, 0], 8), ([0, 0, -1, -1, 0, 1, 1, -1, 0], 1), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 5), ([1, 0, -1, -1, -1, 1, 0, 0, 0], 6), ([0, -1, 1, 0, -1, 0, -1, 1, 0], 8), ([0, 1, 0, 0, -1, -1, 1, -1, 0], 3), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, 0, 0, 1, -1, -1, -1, 0, 1], 2), ([0, 0, 0, -1, 0, 0, 0, -1, 1], 2), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 1), ([-1, 0, 0, 1, -1, -1, 1, 0, 0], 8), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([0, 0, 0, 0, -1, 0, 1, -1, 0], 1), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, 0, -1, 1, -1, -1, 0, 0, 1], 6), ([0, 0, -1, 0, 0, 0, 1, -1, 0], 4), ([-1, 0, 0, -1, 0, 1, 1, -1, 0], 2), ([-1, 0, 0, 0, 0, -1, 0, 0, 1], 4), ([0, 0, -1, -1, -1, 1, 0, 0, 1], 6), ([1, -1, 0, -1, 0, 0, 0, 1, -1], 5), ([-1, 0, 0, 0, 0, -1, 0, 0, 1], 4), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 6), ([0, -1, 1, 0, -1, 0, 0, 0, 0], 7), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 6), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 8), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([1, -1, -1, 0, 0, 0, 0, 0, 0], 3), ([0, -1, 1, 0, 0, -1, -1, 1, 0], 3), ([0, 0, -1, -1, -1, 1, 0, 0, 1], 6), ([0, 0, 0, 0, 0, 0, 1, -1, -1], 3), ([1, 0, -1, -1, 0, 0, 0, 0, 0], 4), ([1, 1, -1, 0, -1, 0, 0, -1, 0], 6), ([0, -1, 1, 0, -1, -1, 0, 1, 0], 3), ([0, -1, 1, -1, -1, 0, 0, 1, 0], 5), ([1, -1, -1, 0, -1, 0, 0, 1, 0], 6), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 2), ([0, 0, 0, 0, 0, 0, -1, -1, 1], 5), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([-1, 1, -1, 0, 1, 0, 0, 1, 0], 8), ([0, -1, 1, -1, -1, 0, 0, 1, 0], 5), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 7), ([-1, 0, 0, 0, 0, -1, 0, 0, 1], 4), ([0, 0, 0, 1, -1, -1, 0, -1, 1], 1), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 2), ([0, -1, 0, 0, 0, -1, 0, 0, 1], 6), ([0, -1, 1, 0, 1, -1, -1, 0, 0], 8), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([1, 0, -1, -1, -1, 1, 0, 0, 0], 6), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 6), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([1, 0, 0, -1, -1, 1, 0, 0, -1], 2), ([0, 0, 1, 0, -1, 0, -1, 0, 0], 0), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([1, -1, 0, 0, -1, 0, 0, 0, 0], 7), ([1, 0, 0, -1, 0, 0, -1, 0, 0], 1), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 8), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 7), ([0, 1, 0, 0, -1, -1, 0, -1, 1], 3), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([1, -1, -1, 0, -1, 0, 0, 1, 0], 6), ([0, 0, -1, 1, 1, 1, 0, 0, -1], 0), ([-1, 0, 0, 0, 0, 0, 0, -1, 1], 4), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([0, -1, 1, 0, 1, -1, -1, 0, 0], 8), ([-1, 1, -1, 0, 1, 0, 0, 1, 0], 8), ([1, 0, 0, -1, -1, 1, -1, 0, 0], 2), ([1, -1, 0, -1, -1, 0, 0, 1, 0], 5), ([0, -1, 0, 0, 0, -1, 0, 0, 1], 6), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 0), ([0, 0, 1, 0, -1, -1, 0, 0, 0], 3), ([0, 0, -1, 0, 0, 0, 1, -1, 0], 4), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 0), ([0, -1, 0, 0, -1, 0, 1, 0, 0], 7), ([0, 0, 1, 0, -1, 0, -1, 0, 0], 0), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 0), ([1, -1, -1, -1, 0, 1, 0, 0, 0], 7), ([0, 0, 0, 0, 0, -1, 1, -1, 0], 0), ([0, -1, 1, 0, 0, -1, 0, 0, 0], 7), ([-1, 1, 0, 0, -1, 0, 0, -1, 1], 2), ([0, 0, 1, 0, 0, -1, 0, -1, 0], 0), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([-1, 1, 0, -1, 0, 0, 1, -1, 0], 5), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([-1, 0, 0, 0, -1, 0, 1, -1, 1], 1), ([0, 1, 0, 0, 1, 0, -1, 1, -1], 0), ([-1, 0, 0, 1, 1, 1, -1, 0, 0], 8), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 2), ([1, -1, 0, 0, 0, -1, 0, 0, 0], 6), ([0, 0, 0, -1, -1, 1, 1, 0, -1], 0), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 6), ([1, -1, 0, 0, -1, -1, 0, 1, 0], 3), ([1, -1, 0, 0, -1, 0, 0, 1, -1], 6), ([-1, 1, 0, 0, -1, 0, 0, -1, 1], 2), ([-1, 1, 0, 0, -1, 0, 0, -1, 1], 2), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 8), ([1, -1, 1, 0, -1, 0, -1, 0, 0], 8), ([1, 0, -1, 0, -1, 0, 0, 0, 0], 6), ([0, 0, 1, 0, 0, -1, -1, 0, 0], 4), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 8), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 6), ([0, 0, 0, -1, 0, 1, 1, -1, -1], 1), ([1, 0, 0, -1, 0, 0, 0, 0, -1], 4), ([0, 0, 1, -1, -1, 1, 0, 0, -1], 0), ([0, 0, 0, 0, 0, 0, -1, -1, 1], 5), ([-1, 0, 0, 1, 1, 1, -1, 0, 0], 8), ([-1, 0, 0, 1, -1, -1, 0, 0, 1], 6), ([0, 1, -1, 0, 0, -1, 0, -1, 1], 3), ([1, 0, 0, 0, -1, -1, 0, 0, 0], 3), ([-1, 0, 0, 0, 1, 0, 0, -1, 0], 8), ([0, 1, 0, 0, -1, -1, 1, -1, 0], 3), ([1, -1, 0, 0, 0, 0, -1, 0, 0], 4), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([0, 0, -1, 0, -1, 0, 1, -1, 1], 0), ([-1, 0, 0, 0, 0, 0, 1, -1, 0], 4), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 8), ([0, 0, 0, 0, -1, -1, 0, 0, 1], 3), ([0, 0, 0, -1, 0, 1, 1, -1, -1], 1), ([-1, 1, 0, -1, 0, 0, 1, -1, 0], 5), ([1, 0, -1, 0, -1, 0, 0, 0, 0], 6), ([0, 0, 0, -1, 0, 0, 0, -1, 1], 2), ([-1, 0, 0, 0, 1, 0, 0, 0, -1], 7), ([0, -1, 0, 1, -1, -1, 0, 0, 1], 7), ([1, -1, 0, -1, 1, 0, 0, 0, -1], 6), ([1, 0, 0, 0, -1, 0, 0, -1, 0], 1), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 2), ([0, 1, -1, 0, -1, 0, 1, -1, 0], 0), ([-1, -1, 1, 0, -1, 0, 0, 1, 0], 8), ([0, 0, -1, -1, -1, 1, 0, 0, 1], 6), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([-1, 0, 0, 0, 1, 0, 0, -1, 0], 8), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([1, -1, 0, 0, 0, -1, 0, 0, 0], 6), ([1, 0, 0, 1, -1, -1, -1, 0, 0], 2), ([0, 1, 0, 0, 1, 0, -1, 1, -1], 2), ([0, 1, 0, 0, -1, 0, -1, -1, 1], 2), ([1, 0, 0, 0, -1, -1, 0, 0, 0], 3), ([0, 0, 0, 0, -1, 0, 1, -1, 0], 1), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([1, 0, 0, -1, -1, 1, -1, 0, 0], 2), ([-1, 0, 0, -1, 0, 0, 1, 0, 0], 7), ([0, 0, 1, 1, -1, -1, -1, 0, 0], 0), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 1), ([1, 0, 0, -1, -1, 1, 0, -1, 0], 1), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 2), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([0, 1, 0, 0, -1, 0, -1, -1, 1], 2), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 5), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([0, 0, 0, 0, 0, -1, 0, 0, 0], 8), ([-1, 1, 0, 0, 0, -1, 0, -1, 1], 3), ([0, 0, 0, -1, 1, 0, 0, 0, -1], 0), ([1, -1, 0, 0, -1, 0, 0, 0, 0], 7), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 5), ([0, 0, 1, 1, -1, -1, -1, 0, 0], 0), ([-1, 1, 0, -1, 0, 0, 1, -1, 0], 5), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([1, -1, 0, 0, -1, -1, 0, 1, 0], 3), ([1, -1, 0, 0, 0, 0, -1, 0, 0], 4), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, -1, 1, 1, 1, 0, 0, -1], 0), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 1, 1, -1, -1], 1), ([0, 1, 0, 0, 1, 0, -1, 1, -1], 0), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 5), ([-1, 1, 0, 0, 0, -1, 0, -1, 1], 3), ([-1, 0, 0, 0, -1, 0, 1, 0, 0], 8), ([0, 0, 1, 0, -1, 0, 0, 0, -1], 0), ([1, -1, 0, -1, 0, 1, -1, 0, 0], 8), ([0, -1, 0, 0, 0, -1, 0, 0, 1], 6), ([0, 0, -1, 1, -1, -1, 0, 0, 1], 6), ([1, 0, 0, -1, -1, 1, 0, -1, 0], 1), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 0), ([1, -1, 0, -1, -1, 0, 0, 1, 0], 5), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 6), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([-1, 0, 0, 1, 0, -1, 0, -1, 1], 1), ([0, -1, 1, 0, 0, -1, 0, 1, -1], 3), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([1, -1, 0, 0, 0, -1, 0, 0, 0], 6), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([1, -1, 1, 0, -1, 0, -1, 0, 0], 8), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([1, 0, -1, 0, -1, 0, 0, 0, 0], 6), ([1, -1, 1, 0, -1, 0, -1, 0, 0], 8), ([-1, 0, 0, 0, -1, 0, 1, 0, 0], 8), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([1, -1, 1, 0, -1, 0, -1, 0, 0], 8), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 7), ([-1, 0, 0, 0, -1, 0, 1, -1, 1], 2), ([0, 0, 0, 0, 0, 0, 0, 0, -1], 4), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, 0, 0, 0, 0, 0, 1, -1, -1], 3), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 0), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([-1, 0, 0, 0, 1, 0, 0, 0, -1], 1), ([0, -1, 1, 1, 0, -1, 0, 0, -1], 6), ([1, 0, -1, -1, -1, 1, 0, 0, 0], 6), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([1, -1, 0, 0, -1, -1, 0, 1, 0], 3), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([1, -1, 0, -1, -1, 1, 0, 0, 0], 7), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 1, 1, -1, -1], 1), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 1, -1, 0, 0, -1, 0, -1, 1], 3), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 3), ([-1, 0, 1, 0, -1, 0, 0, 0, 0], 8), ([1, -1, -1, -1, 0, 0, 0, 1, 0], 8), ([1, 0, 0, -1, 0, 0, 0, 0, -1], 4), ([1, 0, 0, -1, -1, 0, 0, 0, 0], 5), ([1, 0, 0, -1, -1, 1, -1, 0, 0], 2), ([0, 0, -1, 0, 0, 0, 1, -1, 0], 4), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 0, 1, 0, -1, 0, 0, 0, -1], 0), ([1, -1, -1, -1, 0, 1, 0, 0, 0], 7), ([1, 0, 0, -1, -1, 0, 0, 0, 0], 5), ([0, 0, 1, -1, -1, 1, 0, 0, -1], 0), ([0, 0, -1, 1, 0, -1, 0, -1, 1], 0), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 1), ([0, 0, 1, 0, 0, -1, 0, 0, -1], 1), ([1, 0, 0, 0, -1, -1, 0, 0, 0], 3), ([1, 0, 0, -1, 0, 0, 0, -1, 0], 2), ([0, 0, -1, 1, 0, -1, 0, -1, 1], 0), ([0, 0, 0, 0, -1, 0, 1, 0, -1], 0), ([0, 0, 0, 0, 0, -1, 0, -1, 1], 1), ([-1, 0, 0, 0, 1, -1, 0, -1, 1], 2), ([-1, 0, 0, 0, 1, -1, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 1, 1, -1, -1], 1), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 6), ([0, 0, 0, 0, 0, 0, 0, 0, -1], 4), ([-1, 1, 0, -1, 0, 0, 1, -1, 0], 5), ([-1, 0, 0, 0, 1, 0, 0, 0, -1], 5), ([1, -1, 0, 0, 0, 0, -1, 0, 0], 4), ([1, -1, 0, 0, -1, -1, 0, 1, 0], 3), ([0, 1, 0, 0, -1, -1, 1, -1, 0], 3), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([0, -1, 1, 0, 0, -1, 0, 1, -1], 3), ([0, 0, -1, 0, 0, 0, 0, 0, 0], 4), ([1, -1, 0, -1, -1, 0, 0, 1, 0], 5), ([0, 0, 0, 0, -1, 0, 1, 0, -1], 0), ([-1, -1, 1, 1, 0, -1, 0, 0, 0], 7), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 7), ([-1, 0, 1, 1, -1, -1, 0, 0, 0], 8), ([0, -1, 1, 0, -1, 0, -1, 1, 0], 8), ([0, 0, 0, 0, 0, -1, 0, -1, 1], 3), ([0, 0, 0, 0, 0, 0, 1, -1, -1], 3), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([0, -1, 1, -1, 0, 0, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 0, 0, -1, 1], 2), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 6), ([-1, 0, 0, 0, 1, -1, 0, 0, 0], 8), ([-1, 1, 0, 0, -1, 0, 1, -1, 0], 8), ([1, 0, 0, -1, -1, 1, -1, 0, 0], 2), ([1, -1, 0, -1, 0, 0, 0, 1, -1], 5), ([1, 0, 0, 1, -1, -1, -1, 0, 0], 2), ([0, -1, 1, 1, 0, -1, 0, 0, -1], 6), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, 1, -1, 0, -1, 0, 0, -1, 1], 6), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 2), ([-1, 0, 0, 0, -1, 0, 1, -1, 1], 1), ([0, -1, 1, 0, 0, 0, 0, 0, -1], 4), ([1, -1, 0, -1, 0, 1, -1, 0, 0], 8), ([0, 0, -1, 0, 0, -1, 0, 0, 1], 7), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 5), ([0, 1, 0, -1, -1, 0, 0, -1, 1], 5), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([1, -1, 0, -1, 1, 0, 0, 0, -1], 2), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, 0, -1, 1, -1, -1, 0, 0, 1], 6), ([0, 1, 0, -1, -1, 0, 1, -1, 0], 5), ([-1, 0, 0, 1, -1, -1, 0, 0, 1], 6), ([0, 0, 0, 0, 1, -1, -1, 0, 0], 2), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([-1, 0, 0, 0, 1, 0, 0, 0, -1], 1), ([0, -1, 1, 0, -1, 0, -1, 1, 0], 8), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([-1, -1, 1, 0, 0, -1, 0, 1, 0], 6), ([0, 1, -1, 0, -1, 0, 0, -1, 1], 6), ([0, 1, -1, 0, -1, 0, 1, -1, 0], 0), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 2), ([1, -1, 0, -1, 0, 1, -1, 0, 0], 8), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 7), ([0, 0, -1, -1, -1, 1, 0, 0, 1], 6), ([0, 0, 1, 0, -1, -1, 0, 0, 0], 3), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, -1, 1, 0, 0, 0, -1, 0, 0], 4), ([0, 1, 0, 0, -1, -1, 0, -1, 1], 3), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([1, -1, 0, -1, 0, 0, 0, 1, -1], 5), ([-1, 1, -1, 0, 1, 0, 0, 1, 0], 6), ([0, 0, -1, -1, 1, 0, 1, -1, 0], 8), ([-1, 1, 0, 0, 0, -1, 0, -1, 1], 3), ([1, -1, -1, -1, 0, 0, 0, 1, 0], 8), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([0, 0, 1, 0, -1, 0, 0, 0, -1], 0), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 8), ([0, 1, 0, 0, 0, -1, -1, -1, 1], 0), ([0, 0, -1, 0, 1, 0, 0, -1, 0], 6), ([-1, 1, -1, 0, 1, 0, 0, 1, 0], 6), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 0), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 0), ([1, 0, -1, 0, -1, 0, 0, 0, 0], 6), ([1, 0, 0, -1, -1, 1, -1, 0, 0], 2), ([-1, 0, 0, 1, 0, -1, 0, -1, 1], 1), ([0, -1, 0, 0, 0, -1, 0, 0, 1], 6), ([0, 0, -1, 1, 1, 1, 0, 0, -1], 6), ([0, 1, 0, 0, -1, 0, 1, -1, -1], 0), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([0, -1, 1, 1, -1, -1, 0, 0, 0], 7), ([0, 0, 0, 1, -1, -1, -1, 0, 1], 2), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, 0, 0, 0, 0, -1, 0, 0], 4), ([0, -1, 1, 0, 1, -1, -1, 0, 0], 0), ([-1, 0, 0, 0, 1, 0, 0, 0, -1], 5), ([0, 1, 0, 0, -1, -1, 0, -1, 1], 3), ([0, 1, -1, 0, -1, 0, 0, -1, 1], 6), ([0, 0, -1, 1, 1, 1, 0, 0, -1], 0), ([1, -1, -1, -1, 0, 0, 0, 1, 0], 8), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([0, 1, 0, -1, -1, 0, 0, -1, 1], 5), ([1, -1, 0, -1, -1, 0, 0, 1, 0], 5), ([1, -1, 0, -1, 0, 0, 0, 1, -1], 5), ([1, 1, -1, 0, -1, 0, 0, -1, 0], 6), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([1, -1, 0, -1, -1, 0, 0, 1, 0], 5), ([0, 1, 0, -1, 0, 0, 1, -1, -1], 2), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 2), ([0, 1, 0, 0, -1, -1, 1, -1, 0], 3), ([-1, 0, 0, 1, -1, -1, 0, 0, 1], 6), ([0, 1, 0, 0, 1, 0, -1, 1, -1], 0), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([0, -1, 1, -1, -1, 0, 0, 1, 0], 5), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, -1, -1, 1, 0, 0, 0, 0], 6), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 5), ([0, 0, -1, 0, -1, 0, 1, -1, 1], 1), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 2), ([-1, 0, 0, 1, -1, -1, 0, 0, 1], 6), ([1, 0, 0, -1, 0, 0, 0, 0, -1], 4), ([1, 0, 0, -1, 0, 0, 0, -1, 0], 2), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([1, -1, 0, 0, -1, 0, -1, 1, 0], 2), ([0, 0, 0, -1, -1, 1, 1, -1, 0], 1), ([0, -1, 1, 0, 1, -1, -1, 0, 0], 8), ([0, -1, 1, 0, 0, -1, -1, 1, 0], 3), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 0), ([0, 1, -1, 0, -1, 0, 0, -1, 1], 6), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 8), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 0), ([1, 0, 0, -1, -1, 0, 1, 0, -1], 5), ([0, -1, 1, 0, -1, 0, -1, 1, 0], 8), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([0, 0, -1, 0, -1, 0, 0, 0, 1], 6), ([0, -1, 0, 0, 0, -1, 0, 0, 1], 6), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 5), ([0, 0, 0, 0, 0, -1, 0, 0, 0], 0), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 2), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 1), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 5), ([1, -1, 0, 0, 0, -1, 0, 0, 0], 6), ([0, -1, 0, 0, -1, 0, -1, 1, 1], 2), ([1, 1, -1, 0, -1, 0, 0, -1, 0], 6), ([0, 0, 1, 0, 0, -1, -1, 0, 0], 4), ([0, 0, 1, 1, -1, -1, 0, -1, 0], 1), ([0, 0, 0, 0, 0, -1, 0, -1, 1], 1), ([0, -1, 0, -1, -1, 1, 1, 0, 0], 7), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 8), ([0, 0, 1, 0, -1, 0, -1, 0, 0], 0), ([0, -1, 1, 0, 0, -1, 0, 0, 0], 7), ([0, 0, 0, 1, -1, -1, 0, -1, 1], 1), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 7), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([0, 0, 1, 0, -1, 0, 0, 0, -1], 0), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 5), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([0, 0, 0, 0, 0, -1, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 0), ([0, 0, 0, 1, -1, -1, 0, -1, 1], 1), ([0, 1, -1, 0, 0, -1, 0, -1, 1], 3), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 0), ([-1, 0, 0, -1, 0, 1, 1, -1, 0], 2), ([0, 1, 0, 0, 0, -1, -1, -1, 1], 0), ([-1, 0, 0, 1, 0, -1, 0, -1, 1], 1), ([0, -1, 1, 0, 1, -1, -1, 0, 0], 8), ([0, 0, -1, 0, -1, 0, 1, -1, 1], 0), ([0, 0, 0, 0, 0, 0, 1, -1, -1], 3), ([0, 0, 0, 1, -1, -1, -1, 0, 1], 2), ([-1, 0, 0, -1, 0, 0, 1, 0, 0], 7), ([0, 0, 1, 0, 0, -1, 0, -1, 0], 0), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([0, -1, 1, 0, 0, -1, -1, 1, 0], 3), ([0, 0, -1, 0, 0, 0, 0, 0, 0], 4), ([0, 0, 1, 0, 0, -1, -1, 0, 0], 4), ([-1, 0, 0, 1, 0, -1, 0, -1, 1], 1), ([1, 0, 0, -1, 0, 0, -1, 0, 0], 1), ([-1, 0, 0, 0, 1, -1, 0, -1, 1], 2), ([0, 0, 0, 0, 1, -1, -1, 0, 0], 2), ([0, 0, -1, 1, 0, -1, 0, -1, 1], 0), ([0, 0, 0, 0, 0, -1, 0, 0, 0], 2), ([-1, 0, 0, 0, -1, 0, 1, -1, 1], 1), ([0, 0, -1, -1, 1, 0, 0, 0, 0], 6), ([-1, 1, 0, 0, -1, 0, 1, -1, 0], 8), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 6), ([0, -1, 0, 1, -1, -1, 0, 0, 1], 7), ([1, 0, -1, -1, -1, 0, 1, 0, 0], 8), ([0, 0, 0, 0, 0, 0, 1, -1, -1], 3), ([1, -1, 0, -1, 0, 1, 0, 0, -1], 7), ([0, -1, 1, 0, 0, -1, -1, 1, 0], 3), ([1, -1, 0, -1, 0, 0, 0, 0, 0], 5), ([-1, 1, 0, 0, -1, 0, 0, -1, 1], 2), ([0, -1, 1, -1, -1, 0, 0, 1, 0], 5), ([1, -1, 0, 0, 0, 0, -1, 0, 0], 4), ([0, 0, 0, 0, 0, -1, 1, -1, 0], 0), ([0, -1, 1, 0, 0, -1, 0, 0, 0], 3), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 0), ([0, -1, 0, 0, 1, 0, -1, 0, 0], 2), ([-1, 1, 1, 0, -1, 0, 0, -1, 0], 8), ([0, 0, 0, 0, 0, 0, 0, -1, 0], 8), ([0, 0, 1, 0, 0, -1, 0, 0, -1], 1), ([1, 0, 0, 0, -1, 0, -1, 0, 0], 2), ([-1, 0, 0, 0, 0, 0, 0, 0, 0], 4), ([1, 0, 0, 1, -1, -1, -1, 0, 0], 2), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([-1, 1, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, 1, 0, -1, 0, 0, 0, -1], 0), ([0, 0, 0, 0, 0, 0, 0, 0, -1], 4), ([-1, 0, 0, 0, 1, -1, 0, 0, 0], 8), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 7), ([0, 1, -1, -1, 0, 0, 1, -1, 0], 5), ([0, 0, -1, 0, 0, 0, 0, -1, 1], 4), ([1, -1, 0, -1, 0, 1, 0, 0, -1], 7), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([0, 1, 0, 0, -1, -1, 1, -1, 0], 3), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([0, 0, -1, 0, 1, 0, -1, 0, 0], 7), ([0, 0, 0, -1, -1, 0, 0, 0, 1], 5), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 0), ([-1, -1, 1, 0, 0, 0, 0, 0, 0], 5), ([0, 0, -1, 0, 0, -1, 0, 0, 1], 7), ([0, 0, -1, 0, -1, 0, 1, 0, 0], 0), ([1, -1, 0, 0, -1, -1, 0, 1, 0], 3), ([0, 0, 0, 0, -1, 0, 0, -1, 1], 1), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 0), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 6), ([0, 0, 0, 0, 0, -1, 0, 0, 0], 6), ([0, 1, -1, 0, -1, 0, 0, -1, 1], 6), ([-1, -1, 1, 1, 0, -1, 0, 0, 0], 7), ([0, 0, 1, 0, 0, -1, 0, 0, -1], 1), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([0, 0, 0, 0, 0, -1, 0, -1, 1], 1), ([0, 0, 0, -1, 0, 0, 1, -1, 0], 5), ([0, 0, 1, 0, -1, -1, -1, 0, 1], 3), ([-1, 1, 0, 0, -1, 0, 1, -1, 0], 8), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 2), ([0, -1, 0, 0, 0, 0, 0, 0, 0], 0), ([0, 0, 0, 1, -1, -1, -1, 0, 1], 2), ([0, -1, 0, -1, 0, 0, 1, 0, 0], 8), ([0, 0, 0, -1, 0, 0, 1, 0, -1], 4), ([1, 0, 0, -1, 0, 0, 0, -1, 0], 2), ([-1, 0, 0, 1, 1, 1, -1, 0, 0], 8), ([1, 0, 0, 0, -1, 0, 0, -1, 0], 1), ([-1, 0, 0, 0, -1, 0, 0, 0, 1], 6), ([-1, 0, 1, 0, -1, -1, 0, 0, 1], 3), ([1, -1, 1, 0, -1, 0, 0, 0, -1], 7), ([0, 0, 1, 0, 0, -1, -1, 0, 0], 4), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 0, 0, 0, -1, 0, 0, 0, 0], 8), ([0, 0, 0, -1, 0, 0, 0, 0, 0], 6), ([1, 0, 0, 0, -1, 0, 0, 0, -1], 6), ([0, 0, 0, 0, 0, 0, 0, 0, -1], 4), ([0, -1, 0, 0, 1, 0, 0, 0, -1], 0), ([1, 0, 0, -1, -1, 0, 0, 0, 0], 5)]\n"
     ]
    }
   ],
   "source": [
    "sess = tf.Session()\n",
    "moves = get_moves_from_csv('base_tic_tac_toe_moves.csv')\n",
    "train_length = 500\n",
    "train_set = []\n",
    "for t in range(train_length):\n",
    "    train_set.append(get_rand_move(moves))\n",
    "\n",
    "print(train_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "test_board = [-1, 0, 0, 1, -1, -1, 0, 0, 1]\n",
    "train_set = [x for x in train_set if x[0] != test_board]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def init_weights(shape):\n",
    "    return(tf.Variable(tf.random_normal(shape)))\n",
    "\n",
    "\n",
    "def model(X, A1, A2, bias1, bias2):\n",
    "    layer1 = tf.nn.sigmoid(tf.add(tf.matmul(X, A1), bias1))\n",
    "    layer2 = tf.add(tf.matmul(layer1, A2), bias2)\n",
    "    return(layer2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(\"Add_1:0\", shape=(?, 9), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "X = tf.placeholder(dtype=tf.float32, shape=[None, 9])\n",
    "Y = tf.placeholder(dtype=tf.int32, shape=[None])\n",
    "\n",
    "A1 = init_weights([9, 81])\n",
    "bias1 = init_weights([81])\n",
    "A2 = init_weights([81, 9])\n",
    "bias2 = init_weights([9])\n",
    "\n",
    "model_output = model(X, A1, A2, bias1, bias2)\n",
    "\n",
    "print(model_output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型构建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=model_output, labels=Y))\n",
    "train_step = tf.train.GradientDescentOptimizer(0.025).minimize(loss)\n",
    "prediction = tf.argmax(model_output, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iteration 0 Loss: 8.60515\n",
      "iteration 500 Loss: 1.88184\n",
      "iteration 1000 Loss: 1.63089\n",
      "iteration 1500 Loss: 1.23882\n",
      "iteration 2000 Loss: 1.20562\n",
      "iteration 2500 Loss: 1.4494\n",
      "iteration 3000 Loss: 1.19227\n",
      "iteration 3500 Loss: 0.892312\n",
      "iteration 4000 Loss: 0.998839\n",
      "iteration 4500 Loss: 1.1717\n",
      "iteration 5000 Loss: 1.03103\n",
      "iteration 5500 Loss: 1.07898\n",
      "iteration 6000 Loss: 1.02718\n",
      "iteration 6500 Loss: 0.817845\n",
      "iteration 7000 Loss: 0.993813\n",
      "iteration 7500 Loss: 0.745871\n",
      "iteration 8000 Loss: 0.848545\n",
      "iteration 8500 Loss: 0.836112\n",
      "iteration 9000 Loss: 0.923733\n",
      "iteration 9500 Loss: 0.757212\n"
     ]
    }
   ],
   "source": [
    "init = tf.global_variables_initializer()\n",
    "sess.run(init)\n",
    "loss_vec = []\n",
    "for i in range(10000):\n",
    "    rand_indices = np.random.choice(range(len(train_set)), batch_size, replace=False)\n",
    "    batch_data = [train_set[i] for i in rand_indices]\n",
    "    x_input = [x[0] for x in batch_data]\n",
    "    y_target = np.array([y[1] for y in batch_data])\n",
    "    sess.run(train_step, feed_dict={X: x_input, Y: y_target})\n",
    "\n",
    "    temp_loss = sess.run(loss, feed_dict={X: x_input, Y: y_target})\n",
    "    loss_vec.append(temp_loss)\n",
    "    if i%500==0:\n",
    "        print('iteration ' + str(i) + ' Loss: ' + str(temp_loss))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEWCAYAAABliCz2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmYFNXZ/vHvA8jmwqJAxA2JREV/GgUFt4ii4hJxjUtc\nEIm+agLEaFBfE9fgFqMCKopGEEFNBDfcQEUxUUEHkNdhGVBgZFhkYNgchIGZ5/dH1Yw9e8/SdE/X\n/bmuuqb71KmqU13Td1Wfqq42d0dERNJfo2Q3QEREdgwFvohIRCjwRUQiQoEvIhIRCnwRkYhQ4IuI\nRIQCX3YIM2tnZgvMrMUOXOZAM3twRy0vHZnZCWaWlex2SP1Q4EeImS01s1OStPhbgTHu/mPYlo/N\nzM3s8NhKZvZaWN4rfN7azJ4zs1VmtsnMFprZrTH13czyzeyHmGFIOPoZ4DIza79jVrE8M2tqZneY\nWVbYzuVm9q6ZnZasNlUlfD0PKH7u7v9x9wOT2SapPwp8STgzawb0A8aVGbUQuDKm3u7AMUBuTJ1H\ngV2Ag4FWQF/gmzLzOdzdd4kZHgJw9y3Au7HLSBQza1LJqAnAOWEb2gD7A8OAsxLdprKqaKNEhAJf\nADCza8zsGzPLM7M3zaxjWG5m9qiZrTazjWb2tZkdGo4708zmhUfey83s5kpm3wNY7+45ZcrHAxeb\nWePw+aXAa0BBTJ2jgBfdfZ27F7n7AnefUINV+5gqwjU8oh1kZovNbI2Z/d3MGsWMv9rM5pvZOjOb\nbGb7lZn292a2CFhUwbxPAU4FznH3Ge5eEA7vufvgmHodzWyimeWa2RIzGxQz7i4z+7eZjQ1f57lm\n1r0G004ws3FmthG4ysyONrPPzWy9ma00s8fNrGlY/5Nw0jnhJ6WLzayXmeXEzPPg8NPZ+rAtfWPG\njTGzJ8zs7bCtM8zs59VuIdlhFPiCmZ0M3A9cBOwJZAMvh6NPA34F/ILgCPsiYG047p/A/7j7rsCh\nwNRKFvH/gIr6gVcA88JlQHAUPLZMnenAUDPrb2ZdarZmAMwHDq+mznlAd+BIgqPxqwHM7Bzgf4Hz\ngXbAf4CXykx7LsEOrWsF8z0FmFHBjq5EuHOZBMwB9gJ6A380sz4x1foSbI/WwJvA4zWY9hyCTxmt\nCXawhcCNwB4En6Z6AzcAuPuvwmmKPzH9q0xbdwqXNwVoDwwExptZbJfPJcDdBJ9mvgGGVrbusuMp\n8AXgMuA5d5/l7luB24BjzKwTsA3YFTgIMHef7+4rw+m2AV3NbLfwCHxWJfNvDWyqZNxY4EozOwho\n7e6flxk/kCCo/gDMCz+FnFGmzqzwiLN4iA28TQQ7qqo86O557v4d8BjBJw2A64D7w3XeDtwH/DL2\nKD8cn1d8bqKMPYBVxU/MrG3Yvg1mtiUsPgpo5+73hEf/iwnOPVwSM5//uvs77l4IvMBPO7B4pv3c\n3V8PPx396O4z3X26u29396XA08CJ1bw+xXoSdK89EC5vKvBWzOsF8Jq7fxG+XuOBX8Y5b9kBFPgC\n0JHgqB4Ad/+B4Ch+r/BN/TjwBLDazEaZ2W5h1QuAM4FsM5tmZsdUMv91BDuNirwKnEwQ6C+UHRmG\n1H3u3g3YHfg38IqZtY2pdqS7t44ZJseM2xXYUOXaw7KYx9kErwfAfsCw4h0JkAcYwdF0RdOWtZbg\nE1PxuuS5e2ugG9AsZhkdY3dYBJ8qOsTMZ1XM481A87A/Pp5pS7XPzH5hZm9ZcBJ8I8FObI8q1iFW\nR2CZuxfFlGVT+vUo29Zd4py37AAKfIGgayW2b3pngnBdDuDuw8PA7UrQtfPnsPxLdz+H4OP96wRh\nXJH/C6crx903E5xYvZ4KAr9M3eKA2png5Gc8Dibo8qjKPjGP9yV4PSAIy/8pszNp4e6fxTarivl+\nCBxlZntXUWcZsKTMMnZ19zOraXO805Zt30hgAdDF3Xcj2EFYHMuC4HXZJ/YcB8HrtTzO6SXJFPjR\ns5OZNY8ZmhD0S/c3s19acEXNfQR9z0vN7Cgz6xH23+YDW4AiCy43vMzMWrn7NmAjUFTJMr8AWpvZ\nXpWM/1/gxLCLoRQz+2vYhqZm1hwYDKyn4nMCFTmRYIdSlT+bWRsz2yecf3Hf9VPAbWZ2SNiWVmb2\nmziXi7tPAT4CXg9fw6bh69gzptoXwCYzu8XMWphZYzM71MyOimMRtZl2V4Jt9UPYjXZ9mfHfA50r\nmXYGwVH7EDPbyYJLZ8/mp/M9kuIU+NHzDvBjzHCXu38A/BWYCKwEfs5P/cC7EfQLryP4+L4W+Hs4\n7gpgadg1cB3BuYBy3L0AGANcXsn4Fe7+30ra68BoYA3BEeapwFlht1Ox4qtKiofHAMIdxJnA85W+\nGoE3gJnAV8DbBCejcffXgAeBl8N1zATKnj+oznkE/dzjCHZUSwhepz7hMgqBXxP0dS8J1/NZqj/v\nUNtpbwZ+S3Bu4xl+2rkVuwt4PuwiuqjM8goIAv6McFlPAle6+4Lq2iqpwfQDKLIjmFnxVS5HVHKC\nMxHLHAjs4+5DqqjjBN0bZa/tF0k7CnyJNAW+RIm6dEREIkJH+CIiEaEjfBGRiEipmyntscce3qlT\np2Q3Q0SkwZg5c+Yad28XT92UCvxOnTqRkZGR7GaIiDQYZpZdfa2AunRERCJCgS8iEhEKfBGRiFDg\ni4hEhAJfRCQiFPgiIhGhwBcRiYi0CPwpU6awZMmSZDdDRCSlpdQXr2qrT58+mBlFRZX9/oaIiKTF\nET6AbgInIlK1tAl8ERGpmgJfRCQiFPgiIhGhwBcRiQgFvohIRKTFZZmNGzfmyiuvTHYzRERSWloc\n4bdp04YWLVokuxkiIiktLQJfRESqp8AXEYmItAl8fdNWRKRqaRH4ZpbsJoiIpLy0CHwREale2gS+\nunRERKqWFoGvLh0RkeqlReCLiEj1Ehr4Znajmc01s0wze8nMmidyeSIiUrmEBb6Z7QUMArq7+6FA\nY+CSRC1PffgiIlVLdJdOE6CFmTUBWgIrErEQ9eGLiFQvYYHv7suBh4HvgJXABnefkqjliYhI1RLZ\npdMGOAfYH+gI7Gxml1dQ71ozyzCzjNzc3FovT106IiJVS2SXzinAEnfPdfdtwKvAsWUrufsod+/u\n7t3btWtXqwWpS0dEpHqJDPzvgJ5m1tKCRO4NzE/g8kREpAqJ7MOfAUwAZgFfh8salajliYhI1RL6\ni1fufidwZyKXEbOsHbEYEZEGKy2+aas+fBGR6qVF4IuISPUU+CIiEZE2ga8+fBGRqqVF4KsPX0Sk\nemkR+CIiUr20CXx16YiIVC0tAl9dOiIi1UuLwBcRkeop8EVEIiJtAl99+CIiVUuLwFcfvohI9dIi\n8EVEpHoKfBGRiEibwFcfvohI1dIi8NWHLyJSvbQIfBERqV7aBL66dEREqpYWgb9s2TLmzZuX7GaI\niKS0tAh8gC+++CLZTRARSWlpE/giIlI1Bb6ISEQo8EVEIkKBLyISEQp8EZGIUOCLiESEAl9EJCIU\n+CIiEaHAFxGJCAW+iEhEKPBFRCJCgS8iEhEKfBGRiFDgi4hEhAJfRCQiFPgiIhGhwBcRiQgFvohI\nRCjwRUQiIqGBb2atzWyCmS0ws/lmdkwilyciIpVrkuD5DwPec/cLzawp0DLByxMRkUokLPDNrBXw\nK+AqAHcvAAoStTwREalaIrt09gdygdFmNtvMnjWznctWMrNrzSzDzDJyc3MT2BwRkWhLZOA3AY4E\nRrr7EUA+cGvZSu4+yt27u3v3du3aJbA5IiLRlsjAzwFy3H1G+HwCwQ5ARESSIGGB7+6rgGVmdmBY\n1BuYl6jliYhI1RJ9lc5AYHx4hc5ioH+ClyciIpVIaOC7+1dA90QuQ0RE4qNv2oqIRIQCX0QkIhT4\nIiIRocAXEYkIBb6ISEQo8EVEIkKBLyISEQp8EZGIUOCLiESEAl9EJCLSIvBPP/30ZDdBRCTlpUXg\nH3jggbRq1SrZzRARSWlpEfhmRlFRUbKbISKS0tIm8N092c0QEUlpaRH4jRo1UuCLiFQjLQJfXToi\nItVLm8DXEb6ISNXiCnwz+7mZNQsf9zKzQWbWOrFNi5+6dEREqhfvEf5EoNDMDgD+CewPvJiwVtXQ\n559/ztatW9m+fXuymyIikrLiDfwid98OnAc85u43Ansmrlk188knnwDw3XffJbklIiKpK97A32Zm\nlwL9gLfCsp0S06TaGzFiRLKbICKSsuIN/P7AMcBQd19iZvsDLySuWbWTnZ2d7CaIiKSsJvFUcvd5\nwCAAM2sD7OruDyayYbWhSzNFRCoX71U6H5vZbmbWFpgDjDazRxLbtJpbsWJFspsgIpKy4u3SaeXu\nG4HzgdHu3g04JXHNqp0vv/wy2U0QEUlZ8QZ+EzPbE7iIn07aiohIAxJv4N8DTAa+dfcvzawzsChx\nzRIRkfoW70nbV4BXYp4vBi5IVKNERKT+xXvSdm8ze83MVofDRDPbO9GNExGR+hNvl85o4E2gYzhM\nCstERKSBiDfw27n7aHffHg5jgHYJbJeIiNSzeAN/rZldbmaNw+FyYG0iGyYiIvUr3sC/muCSzFXA\nSuBC4KoEtUlERBIgrsB392x37+vu7dy9vbufi67SERFpUOryi1d/qrdWiIhIwtUl8K3eWlFHv/vd\n75LdBBGRlFeXwE+Z3xRs2rRpspsgIpLyqvymrZltouJgN6BFQlpUC2Yp82FDRCRlVRn47r5rXRdg\nZo2BDGC5u/+6rvOrZBmJmK2ISFqpS5dOvAYD8xO5AAW+iEj1Ehr44f12zgKeTeRyGjXaEfstEZGG\nLdFJ+RgwBKj0twfN7FozyzCzjNzc3FotREf4IiLVS1jgm9mvgdXuPrOqeu4+yt27u3v3du1qd3se\nBb6ISPUSeYR/HNDXzJYCLwMnm9m4RCxIgS8iUr2EBb673+bue7t7J+ASYKq7X56IZakPX0SkemmR\nlDrCFxGpXlw/cVhX7v4x8HGi5q/AFxGpno7wRUQiIi0CX334IiLVS4ukjD3Cf/HFF5PYEhGR1GXu\nKXPTS7p37+4ZGRk1nm716tV06NCh5HkqrZOISCKZ2Ux37x5P3bQ4wm/fvn2ymyAikvLSIvBFRKR6\nCnwRkYhQ4IuIRIQCX0QkItIy8Ddv3pzsJoiIpJy0DPydd9452U0QEUk5aRn4IiJSngJfRCQiFPgi\nIhGhwBcRiYi0Dfzt27cnuwkiIiklbQP//PPPT3YTRERSStoG/qRJk5LdBBGRlJK2gS8iIqUp8EVE\nIiKtA3/16tVMnDgRM2PNmjXJbo6ISFI1SXYDEumss86iefPmAMyfP58TTjghyS0SEUmetDnCP/vs\ns8uVZWRksGTJkiS0RkQk9aRN4Ff2O7bLly+vcryISFSkTeAfdthhyW6CiEhKS5vAHzRoULKbICKS\n0tIm8Js1a5bsJoiIpLS0CfzWrVtXOV59+CISdWkT+NXp1atXspsgIpJUkQl8gA0bNiS7CSIiSROp\nwM/Pz092E0REkiatAv/JJ5+scvx5553Hli1bdlBrRERSS1oF/vXXX1/l+C+++IKTTjqJzz//nOnT\np++gVomIpIa0vpdORaZPn86xxx4L6ModEYmWtDrCFxGRyqVd4P/+97+Pu66u2hGRKEm7wG/fvn3c\ndTMzMyss37BhA/PmzauvJomIpIS0C/xrr72WHj16xFX3+OOPx8wwM/72t7+VlJ988skccsghiWqi\niEhSJOykrZntA4wFOgAOjHL3YYlaXrGf/exnJVfgmFnc0/31r38lLy+PRx99NFFNExFJqkQe4W8H\nbnL3rkBP4Pdm1jWByyvnzDPPrFH9isLe3XXtvoikhYQFvruvdPdZ4eNNwHxgr0QtryLXXXddnaaf\nM2cOf/vb32jRogXr1q0rNW7ZsmUMGjSIwsLCOi1DRGRH2SF9+GbWCTgCmFHBuGvNLMPMMnJzc+t1\nuaeffnqdpp80aRJjx44F4PHHH+e1116joKAAgKuvvpoRI0bwySef1LmdIiI7QsID38x2ASYCf3T3\njWXHu/sod+/u7t3btWtXr8tu3LhxnabPyMjgm2++AeCOO+7g/PPPp1mzZtx6660lR/xFRUU8++yz\nmBlbt26tc5tFRBIloYFvZjsRhP14d381kcuqSKNGjXj77bdrPf0bb7xRYfmDDz7IzJkzgaCP/5pr\nrgHg22+/xd0ZPnw4mzZtKjXN2LFjS3YeVdm6dSsPPfQQ27Ztq3W7RUQqkrDAt+ASmX8C8939kUQt\npzrbt29P6PwXLVpU8viQQw7h3XffZfDgwey2225kZWWVjOvXrx9dunQpeT58+HC+++67cvN76KGH\nuOWWWxg1alRC2y0i0ZPII/zjgCuAk83sq3Co2WUz9aA48M8777yEzP+GG24o9fyss84qedy7d28A\nXn755ZKyvLw8br75ZgYPHsx+++3HOeecA8DcuXO5/vrrSz4ZxH5C2Lp1K5dddlmFOwiAV199lfvu\nu69+VihGTk5OpZ9yRKThsVS6gVj37t09IyOjXue5bNky9t13X9555x0OOuggOnfuXK/zr467V/t9\ngJdeeolLL720XHnbtm3585//zC9+8QsuuOACzj33XF577bVy9YrnX9/bcp999iEnJ0c3mRNJYWY2\n0927x1U3ld7MiQj8smryZaxUNGPGDDIzM/nggw94/vnncfeSH3AvKipi2LBhXHzxxey5554VTp+b\nm0v79u0ZOXJktZetJmpHIiL1pyaBn3a3Vkh3PXr0YMCAAbz00ks0bdq0JOwBsrKyuPHGG/nNb37D\nunXruPnmm8ud/F2yZAkA//znP3dou0Uk+SJ3P/zVq1fTqVMnNm/enOym1Ls5c+YAsHHjRvbee282\nb96MmfH3v/+9pE5eXl6N51vcLbVlyxaaN29eb+0VkR0rckf47dq1Y+nSpTz99NPJbkq9u+SSSwD4\n+uuvS3ZoDz/8MOvXry+pc8YZZwDBdwy++uqrUtO7O19++WW5Lhx3Z/r06bRo0YL33nuv0uW/8cYb\ntGrVih9//LFe1kdE6lfkAh+C0L/22mvZsmUL+fn5TJ06NdlNSqg2bdrg7jz//POlyo844gj69evH\ngAEDGDp0KI0aNeLoo4+mdevWpS5nfeqpp/j0008BmDJlChDsBKZNm8aiRYtYvHgxffv2ZeDAgWzc\nuJGePXvyyiuvcPjhh7NxY/Bdu7y8vHK3p4jX0qVLOeaYY2r16UREYrh7ygzdunXzZCG4o6ffdddd\nJY+jPBx88MFx123cuHGl4yZNmuQLFiwoVTZu3Dj//vvv49ouGzZs8GuuucYBHzlyZIL/C0QaHiDD\n48zYSB7hV+Srr74iJyeHO++8s8LxTZpE63TH/Pnz465b1Q3knnnmGQ466KBSZZdffjkdOnTgtNNO\nY+LEiSxfvpx169ZxxRVXsGHDBo488kgmTJjA6tWradWqFc888wxAySeEefPmlfrxmtmzZ5f69bJN\nmzaxePHiuNsvEhnx7hl2xJDMI/xYVHCkeuaZZyb9qDsKwx133OGAN2vWzGfPnl1ufGzZ4sWLS7bX\nUUcdVbL9unXr5sG/du2NGzfOv/zyy3LlI0aM8Oeee65O8xapT9TgCD/pIR87pFrgf/zxxw74fffd\n57m5uT5s2DA/99xzkx6K6TycffbZJY/feOONauuvX7++5HHZ7bdgwQJ3d1+1apXPmzev1Db+97//\n7ccee2y1/wPxlru7b9261efMmVObf7lKFRUV+VtvveVFRUX1Ol9JHwr8OgK8VatWFY7Lz8/3u+++\n24cMGeJr1qzx1atXVxlIxx13XNJDNCrD4MGDfezYsaXKPvroI2/WrJkD/vDDD5faxoB3797db731\nVgf8ggsu8E2bNpUaX2zx4sWldkDFvv32W+/SpYuvWLHCzznnHAe8d+/eNf6fKyoqqjDUR40a5YA+\nVUilFPh1lJmZGfdJRXf3H374we+9917ftm2bZ2dne48ePUqC4T//+U/SgzDKwyGHHFLqeceOHaud\n5u677y4V7IWFheXquAdH9AMGDHDAH3rooXLjK7Ns2TKfP39+qbITTjihwun+8pe/OOD33HNPhfOa\nOnWqjx49Ou7/1ViTJk1ywL/++utaTS+pQYGfAmbPnu1nnHGGFxUVeVZWlrdq1coB79evX7WfCjSk\n/nDZZZf5iSeeWPL8jDPOKDV+xIgRlf5vlN0pdOnSpaTs22+/dfcgjMeMGeO33357SeCvWrXKIbjK\nqey8nnjiCV+/fr1v3LjR3d3XrVvnTz31VJVdQcU7q2eeeaau/+6SRAr8BmDz5s0+dOjQCsNk5cqV\nSQ80DXUfTjrppJLHgwYN8uOPP95nzZpVUvbJJ59UOJ37T0H+29/+1iEI/Pbt2zsEJ6i3bNlSql7x\nsNNOO7m7+29+8xsH/Pbbb6/0f7D4cte//OUvnpmZmfh/+gTavn27v/DCC15YWJjspuxwKPAbjsre\n8NOmTStV1rlz5wrrxh4dakiPYdy4ceXKWrZsWep5u3btKt32rVu3Llc2bNgwd3efOXOmFxUV+aZN\nm/zaa68tVaciX3zxhW/fvt3z8vIS/l6YPXu2r169ulbTDh8+3AF/6qmn6rlVqQ9dh99w3HTTTTRu\n3JjMzEyysrJ45513AGjRokWpevvuu2+5ad2dhQsX4u66GVoaufzyy8uVlb33U25ubqkf34kVeyuN\nYoMHD8bM6NatG40aNWLXXXdl9OjRpeqccMIJLFy4kBtuuIEVK1bw2WefcfTRR9OkSRPatm3L0qVL\nAfjxxx/ZsmVLXOvy2WefkZ2dXaosMzMTM+Pwww8vKZs+fTpHHHEE7du3Jz8/P655x/r++++B4F5Z\nUoV49ww7YojiEX5lioqKfOjQob5y5UofP3685+bmlhyJnXfeeeU+qhcUFPhdd93l06ZN8zVr1nj/\n/v29WbNm3rVr16QfsWpomMOdd95Z6vkpp5ziRx55ZMnzqVOnunvwKWDZsmX+9ttve58+fbxDhw4+\nYsQIz8zMLKnr7v7cc8/52rVrS83T3T07O7tUWcuWLX3z5s2Vvjeuu+4633fffX3p0qW+dOlSz8nJ\nKXdyu+xVT8OHD/cVK1bU+v349NNP+7Rp02o9fSKhLp30dPzxx3uvXr1qNM2NN95Y8kZq06aNH3TQ\nQaXeXGPHjvVBgwYlPVw0NLzhgAMO8KlTpyZs/u7u8+bN8/Xr13tmZqb/8MMPXlBQUGHd4sC/6aab\nfMmSJf7kk0864KtWrfLnnnvOAe/Ro4dPnz693InsoqIinz17drn3TmFhoQ8ZMsSXLl1aqk3FJk+e\nXO7LeU8//bSvXbu20vfjtm3bavT+jQcKfCm2aNEib9q0qX/88cfuHvxz33bbbZ6RkVFyRcfWrVv9\nww8/9M2bN/vmzZt94sSJDvisWbO8qKjIp0yZ4nPnzvW77rrLP/roo6QHjQYNdRmuuOIK79evn0+b\nNs0///zzkosnDjvssFKXqFb0Te9YZcuKT8j37du3VL1169b5e++9V/JJ5uSTT67yE0xNocCXusrP\nz6903Keffurjxo3zY4891oFyN0cr+waJ94343nvvJT0MNGi46KKLKh1XLPYb4RBcTlt8EvznP/+5\nZ2dn+9KlSz07O9v3228/B/ziiy8uqX/hhRf666+/Xu4b4LWBAl92tOKrSNq2bVuqi8jd/ayzzir1\n5pg2bZovXLjQFy1a5OPHj3fA8/LyfPLkySV1Ro8eXeWb8p577kl6MGjQUF9DTk5Ord97KPAl2Yr/\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x5eeb6a0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(loss_vec, 'k-', label='Loss')\n",
    "plt.title('Loss (MSE) per Generation')\n",
    "plt.xlabel('Generation')\n",
    "plt.ylabel('Loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6]\n"
     ]
    }
   ],
   "source": [
    "test_boards = [test_board]\n",
    "feed_dict = {X: test_boards}\n",
    "logits = sess.run(model_output, feed_dict=feed_dict)\n",
    "predictions = sess.run(prediction, feed_dict=feed_dict)\n",
    "print(predictions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def check(board):\n",
    "    wins = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]]\n",
    "    for i in range(len(wins)):\n",
    "        if board[wins[i][0]]==board[wins[i][1]]==board[wins[i][2]]==1.:\n",
    "            return(1)\n",
    "        elif board[wins[i][0]]==board[wins[i][1]]==board[wins[i][2]]==-1.:\n",
    "            return(1)\n",
    "    return(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Input index of your move (0-8): 0\n",
      "Model has moved\n",
      " X |   |  \n",
      "___________\n",
      "   |   |  \n",
      "___________\n",
      " O |   |  \n",
      "Input index of your move (0-8): 2\n",
      "Model has moved\n",
      " X | O | X\n",
      "___________\n",
      "   |   |  \n",
      "___________\n",
      " O |   |  \n",
      "Input index of your move (0-8): 8\n",
      "Model has moved\n",
      " X | O | X\n",
      "___________\n",
      "   |   |  \n",
      "___________\n",
      " O | O | X\n",
      "Input index of your move (0-8): 4\n",
      "Model has moved\n",
      " X | O | X\n",
      "___________\n",
      " O | X |  \n",
      "___________\n",
      " O | O | X\n",
      "Game Over!\n"
     ]
    }
   ],
   "source": [
    "game_tracker = [0., 0., 0., 0., 0., 0., 0., 0., 0.]\n",
    "win_logical = False\n",
    "num_moves = 0\n",
    "while not win_logical:\n",
    "    player_index = input('Input index of your move (0-8): ')\n",
    "    num_moves += 1\n",
    "    game_tracker[int(player_index)] = 1.\n",
    "    [potential_moves] = sess.run(model_output, feed_dict={X: [game_tracker]})\n",
    "    allowed_moves = [ix for ix,x in enumerate(game_tracker) if x==0.0]\n",
    "    model_move = np.argmax([x if ix in allowed_moves else -999.0 for ix,x in enumerate(potential_moves)])\n",
    "    game_tracker[int(model_move)] = -1.\n",
    "    print('Model has moved')\n",
    "    print_board(game_tracker)\n",
    "    if check(game_tracker)==1 or num_moves>=5:\n",
    "        print('Game Over!')\n",
    "        win_logical = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
